<template>
  <div>
    <el-form label-width="80px" :inline="false" size="default">
      <el-form-item label="SPU名称">
        <el-input v-model="spuInfo.spuName"></el-input>
      </el-form-item>
      <el-form-item label="品牌">
        <el-select placeholder="请选择品牌" clearable v-model="spuInfo.tmId">
          <el-option
            v-for="item in trademarkList"
            :key="item.id"
            :label="item.tmName"
            :value="item.id"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
        <el-input
          v-model="spuInfo.description"
          size="default"
          clearable
          type="textarea"
        ></el-input>
      </el-form-item>
      <el-form-item label="SPU图片">
        <el-upload
          v-model:file-list="imageList"
          action="http://gmall-h5-api.atguigu.cn/admin/product/upload"
          list-type="picture-card"
          :on-remove="handleRemove"
          :on-success="handleAvatarSuccess"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性">
        <el-select placeholder="请选择销售属性" v-model="spuSaleInfoTemp">
          <el-option
            v-for="item in unUseSaleAttrList"
            :key="item.id"
            :label="item.name"
            :value="`${item.id}:${item.name}`"
          ></el-option>
        </el-select>

        <el-button
          icon="ele-Plus"
          type="primary"
          style="margin-left: 20px"
          @click="addSaleAttr"
          >添加销售属性</el-button
        >
      </el-form-item>
      <el-form-item>
        <el-table border stripe :data="saleAttrSelf">
          <el-table-column type="index" width="80" label="序号" />
          <el-table-column label="属性名" prop="saleAttrName"></el-table-column>
          <el-table-column label="属性值名称列表">
            <template v-slot="{ row }">
              <el-tag
                type="primary"
                size="small"
                effect="dark"
                closable
                @close="deleteAttrValue(row, index)"
                v-for="(item, index) in row.spuSaleAttrValueList"
                :key="item.id"
                >{{ item.saleAttrValueName }}</el-tag
              >
              <el-button
                v-if="!row.isEdit"
                type="default"
                size="small"
                @click="addAttrValue(row)"
                >新增属性值</el-button
              >
              <el-input
                v-if="row.isEdit"
                placeholder="请新增属性值"
                size="small"
                clearable
                ref="inputEle"
                @blur="toLook(row)"
                v-model="inputValue"
              ></el-input>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template v-slot="{ row, $index }">
              <el-button
                type="danger"
                size="small"
                @click="deleteSaleAttr($index)"
                icon="ele-Delete"
              ></el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="save">保存</el-button>
        <el-button @click="emit('changeType', 0)">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "SpuForm",
});
</script>

<script setup lang="ts">
import { cloneDeep } from "lodash";
import {
  reqAddSpu,
  reqUpdateSpu,
  type saleAttrItemType,
  type spuItemType,
} from "@/api/spu";
import { computed, nextTick, onMounted, ref } from "vue";
import { Plus } from "@element-plus/icons-vue";
import { ElMessage, type UploadProps, type UploadUserFile } from "element-plus";
import { reqAllTrademark, type trademarkListType } from "@/api/trademark";
import {
  reqBaseSaleAttrList,
  type baseSaleAttrListType,
  reqSaleAttrSelf,
  type saleAttrListType,
  reqSpuImageList,
  type spuImgListType,
} from "@/api/spu";
const props = defineProps<{
  spuInfo: spuItemType;
}>();
//接收切换type的自定义事件
const emit = defineEmits<{
  (event: "changeType", type: number, row?: spuItemType): void;
}>();

const dialogImageUrl = ref("");
const dialogVisible = ref(false);

//删除图片墙的图片回调,现在不需要操作,因为默认和imageList进行双向绑定
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  // console.log(uploadFile, uploadFiles, imageList);
};

//添加图片墙图片的时候,我们发现imageList也收集了图片,但是格式并不是我们想要的格式,所以我们还是要进行下一步的处理
const handleAvatarSuccess: UploadProps["onSuccess"] = (
  response,
  uploadFile
) => {
  // console.log(response, uploadFile, c);
  // console.log(imageList);
};

//定义一些值接收初始化请求的信息
const trademarkList = ref<trademarkListType>([]);
const saleAttrList = ref<baseSaleAttrListType>([]);
const saleAttrSelf = ref<saleAttrListType>([]);
const imageList = ref<spuImgListType>([]);

//因为我们将来要对自己的销售属性进行编辑和查看切换,每一条数据上应该保存一个isEdit属性,保存当前的状态
saleAttrSelf.value.forEach((item) => {
  item.isEdit = false;
});

//判断当前是修改还是新增 来发送其他的数据请求
//如果是新增则需要发送1. 所有品牌列表 2.所有销售属性列表
//如果是修改则需要发发送1. 所有品牌列表 2.所有销售属性列表 3.根据当前spuId获取图片列表 4. 根据当前spuId获取销售属性列表
onMounted(async () => {
  try {
    if (props.spuInfo.id) {
      //修改
      const p1 = reqAllTrademark();
      const p2 = reqBaseSaleAttrList();
      const p3 = reqSaleAttrSelf(props.spuInfo.id);
      const p4 = reqSpuImageList(props.spuInfo.id);

      const result = await Promise.all([p1, p2, p3, p4]);
      trademarkList.value = result[0];
      saleAttrList.value = result[1];
      saleAttrSelf.value = result[2];
      imageList.value = result[3];

      //给imageList添加name和url两个属性,方便在图片墙展示的时候使用
      imageList.value.forEach((item) => {
        item.name = item.imgName;
        item.url = item.imgUrl;
      });
    } else {
      //新增
      const p1 = reqAllTrademark();
      const p2 = reqBaseSaleAttrList();
      const result = await Promise.all([p1, p2]);
      trademarkList.value = result[0];
      saleAttrList.value = result[1];
    }
  } catch (e: any) {
    ElMessage.error(e.message);
  }
});

//计算属性计算当前spu没有使用过的销售属性列表
const unUseSaleAttrList = computed(() => {
  return saleAttrList.value.filter((item) => {
    //深层次拿到当前遍历的item 去和 已经存在的销售属性列表一一对比,判断是否已经存在
    return !saleAttrSelf.value.some((selfItem) => {
      console.log(item, selfItem);
      //如果有相等的 则some直接返回true(但是filter要把返回true的过滤掉,所以我们filter中要去一个反即可)
      return selfItem.saleAttrName === item.name;
    });
  });
});

const spuSaleInfoTemp = ref("");

//添加销售属性的回调函数
const addSaleAttr = () => {
  //判断销售属性是否选择
  if (!spuSaleInfoTemp.value) return;
  //获取销售属性收集的id和name
  const [id, name] = spuSaleInfoTemp.value.split(":");
  //向自己的销售属性列表中 新增我们需要的销售属性
  saleAttrSelf.value.push({
    baseSaleAttrId: +id,
    saleAttrName: name,
    spuId: props.spuInfo.id,
    spuSaleAttrValueList: [],
    isEdit: false,
  });

  //清空销售属性的收集的数据
  spuSaleInfoTemp.value = "";
};

//获取新增属性值的表单元素
const inputEle = ref<HTMLInputElement>();
//添加属性值按钮事件函数
const addAttrValue = (row: saleAttrItemType) => {
  row.isEdit = true;
  //让输入框自动获取焦点
  nextTick(() => {
    inputEle.value?.focus();
  });
};

//添加属性值的表单失去焦点事件
const toLook = (row: saleAttrItemType) => {
  row.isEdit = false;
  //首先判断当前的输入的内容是否为空
  if (!inputValue.value) {
    return ElMessage.error("输入不能为空");
  }

  //判断不能和已经存在的属性值相等
  const isRepeat = row.spuSaleAttrValueList.some((item) => {
    return item.saleAttrValueName === inputValue.value;
  });

  if (isRepeat) {
    inputValue.value = "";
    return ElMessage.error("输入不能重复");
  }

  row.spuSaleAttrValueList.push({
    baseSaleAttrId: row.baseSaleAttrId, //后台不需要这个值
    // id: 5//后台不需要这个值
    isChecked: "", //后台不需要这个值
    saleAttrName: row.saleAttrName,
    saleAttrValueName: inputValue.value,
    spuId: props.spuInfo.id, //后台不需要这个值
  });

  inputValue.value = "";
};

//创建一个数据保存添加属性值的时候input的值
const inputValue = ref("");

//当点击tag的时候 删除某个小标
const deleteAttrValue = (row: saleAttrItemType, index: number) => {
  row.spuSaleAttrValueList.splice(index, 1);
};

//当点击删除某一条销售属性的时候
const deleteSaleAttr = (index: number) => {
  saleAttrSelf.value.splice(index, 1);
};

//提交
const save = async () => {
  // console.log(props.spuInfo);
  // console.log(saleAttrSelf.value);
  // console.log(imageList.value);

  //1.处理销售属性列表,如果有isEdit则删除掉
  saleAttrSelf.value.forEach((item) => {
    delete item.isEdit;
  });

  //2. 处理图片列表
  imageList.value = imageList.value.map((item) => {
    //整理数据,因为图片必填以下两项,所以我们操作数据返回下边两项组成的对象
    //不要判断,直接返回值,并且要把类型给断言好
    return {
      imgName: item.name as string,
      imgUrl: item.imgUrl || (item.response.data as string),
    };
  });

  //把刚才整理好的数据交给spuInfo
  props.spuInfo.spuSaleAttrList = saleAttrSelf.value;
  props.spuInfo.spuImageList = imageList.value;

  //发送请求
  try {
    if (props.spuInfo.id) {
      //修改
      await reqUpdateSpu(props.spuInfo);
      ElMessage.success("修改成功");
    } else {
      //修改
      await reqAddSpu(props.spuInfo);
      ElMessage.success("新增成功");
    }

    //切换到spuList
    emit("changeType", 0);
  } catch (e: any) {
    ElMessage.error(e.message);
  }
};
</script>

<style scoped></style>
